#!/bin/bash
###############################################################################
#       脚本名称: test_real_world.sh
#       功能描述: 真实场景集成测试 - 模拟实际应用场景
###############################################################################

cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1

source ../../unit/test_framework.sh
source ../../../scripts/config/config.sh

TEST_DIR=$(create_test_dir)

###############################################################################
# 测试用例
###############################################################################

# 场景1: Web应用配置管理
test_scenario_web_application() {
    # 创建Web应用的配置结构
    local app_yaml="$TEST_DIR/application.yaml"
    local db_ini="$TEST_DIR/database.ini"
    local cache_json="$TEST_DIR/cache.json"
    local secrets_env="$TEST_DIR/.env"
    
    # 应用主配置
    cat > "$app_yaml" << 'EOF'
application:
  name: WebApp
  version: 2.0.0
  environment: production
  
server:
  host: 0.0.0.0
  port: 8080
  workers: 4
  timeout: 30
  
logging:
  level: INFO
  file: /var/log/webapp/app.log
  max_size: 100MB
EOF
    
    # 数据库配置
    cat > "$db_ini" << 'EOF'
[mysql]
host=mysql.example.com
port=3306
database=webapp_prod
pool_size=20
timeout=10

[postgresql]
host=pg.example.com
port=5432
database=webapp_analytics
pool_size=10
EOF
    
    # 缓存配置
    cat > "$cache_json" << 'EOF'
{
  "redis": {
    "host": "redis.example.com",
    "port": 6379,
    "database": 0,
    "ttl": 3600,
    "clusters": [
      "redis1.example.com:6379",
      "redis2.example.com:6379"
    ]
  }
}
EOF
    
    # 敏感信息
    cat > "$secrets_env" << 'EOF'
DB_PASSWORD=super_secret_password
REDIS_PASSWORD=another_secret
API_KEY=sk-1234567890abcdef
JWT_SECRET=jwt_signing_secret
EOF
    
    # 初始化并加载所有配置
    config_init 2>/dev/null
    config_load "$app_yaml" "app" 2>/dev/null
    config_load "$db_ini" "database" 2>/dev/null
    config_load "$cache_json" "cache" 2>/dev/null
    config_load "$secrets_env" "secrets" 2>/dev/null
    
    # 验证应用可以读取各种配置
    local app_name=$(config_get "app" ".application.name" 2>/dev/null)
    assert_equals "WebApp" "$app_name"
    
    local db_host=$(config_get "database" "mysql.host" 2>/dev/null)
    assert_equals "mysql.example.com" "$db_host"
    
    local redis_host=$(config_get "cache" ".redis.host" 2>/dev/null)
    assert_equals "redis.example.com" "$redis_host"
    
    local db_password=$(config_get "secrets" "DB_PASSWORD" 2>/dev/null)
    assert_not_empty "$db_password"
}

# 场景2: 微服务配置中心
test_scenario_microservices() {
    # 服务发现配置
    local service_registry="$TEST_DIR/service_registry.json"
    cat > "$service_registry" << 'EOF'
{
  "services": {
    "user-service": {
      "host": "user-service.internal",
      "port": 8001,
      "health_check": "/health"
    },
    "order-service": {
      "host": "order-service.internal",
      "port": 8002,
      "health_check": "/health"
    },
    "payment-service": {
      "host": "payment-service.internal",
      "port": 8003,
      "health_check": "/health"
    }
  }
}
EOF
    
    # API网关配置
    local gateway_yaml="$TEST_DIR/api_gateway.yaml"
    cat > "$gateway_yaml" << 'EOF'
gateway:
  port: 80
  routes:
    - path: /api/users
      service: user-service
      timeout: 30
    - path: /api/orders
      service: order-service
      timeout: 60
    - path: /api/payments
      service: payment-service
      timeout: 45
  
rate_limiting:
  enabled: true
  requests_per_minute: 1000
EOF
    
    config_init 2>/dev/null
    config_load "$service_registry" "registry" 2>/dev/null
    config_load "$gateway_yaml" "gateway" 2>/dev/null
    
    # 验证服务配置
    local user_service_port=$(config_get "registry" ".services.\"user-service\".port" 2>/dev/null)
    assert_equals "8001" "$user_service_port"
    
    local gateway_port=$(config_get "gateway" ".gateway.port" 2>/dev/null)
    assert_equals "80" "$gateway_port"
}

# 场景3: CI/CD流水线配置
test_scenario_cicd_pipeline() {
    # 流水线配置
    local pipeline_yaml="$TEST_DIR/pipeline.yaml"
    cat > "$pipeline_yaml" << 'EOF'
pipeline:
  name: webapp-deploy
  stages:
    - name: build
      image: node:16
      commands:
        - npm install
        - npm run build
        - npm test
    - name: deploy
      image: kubectl:latest
      commands:
        - kubectl apply -f k8s/
        - kubectl rollout status deployment/webapp
  
notifications:
  slack:
    enabled: true
    webhook: https://hooks.slack.com/services/XXX
EOF
    
    # 环境变量
    local ci_env="$TEST_DIR/ci.env"
    cat > "$ci_env" << 'EOF'
CI=true
NODE_ENV=production
BUILD_NUMBER=123
GIT_COMMIT=abc123def456
DOCKER_REGISTRY=registry.example.com
EOF
    
    config_init 2>/dev/null
    config_load "$pipeline_yaml" "pipeline" 2>/dev/null
    config_load "$ci_env" "ci_env" 2>/dev/null
    
    # 验证流水线配置
    local pipeline_name=$(config_get "pipeline" ".pipeline.name" 2>/dev/null)
    assert_equals "webapp-deploy" "$pipeline_name"
    
    local build_num=$(config_get "ci_env" "BUILD_NUMBER" 2>/dev/null)
    assert_equals "123" "$build_num"
}

# 场景4: 配置热更新场景
test_scenario_hot_reload() {
    local config_file="$TEST_DIR/app_config.yaml"
    
    # 初始配置
    cat > "$config_file" << 'EOF'
feature_flags:
  new_ui: false
  beta_features: false
  
rate_limits:
  api_calls_per_minute: 100
EOF
    
    config_init 2>/dev/null
    export CONFIG_AUTO_RELOAD=true
    config_load "$config_file" "app_config" 2>/dev/null
    
    # 读取初始值
    local new_ui_v1=$(config_get "app_config" ".feature_flags.new_ui" 2>/dev/null)
    assert_equals "false" "$new_ui_v1"
    
    # 模拟运维人员更新配置
    sleep 1
    cat > "$config_file" << 'EOF'
feature_flags:
  new_ui: true
  beta_features: true
  
rate_limits:
  api_calls_per_minute: 200
EOF
    
    # 再次读取（应该自动重载）
    local new_ui_v2=$(config_get "app_config" ".feature_flags.new_ui" 2>/dev/null)
    assert_equals "true" "$new_ui_v2"
    
    local rate_limit=$(config_get "app_config" ".rate_limits.api_calls_per_minute" 2>/dev/null)
    assert_equals "200" "$rate_limit"
}

# 场景5: 多租户配置隔离
test_scenario_multi_tenant() {
    # 租户A配置
    local tenant_a_ini="$TEST_DIR/tenant_a.ini"
    cat > "$tenant_a_ini" << 'EOF'
[tenant]
id=tenant_a
name=Company A

[database]
host=db-tenant-a.example.com
database=tenant_a_db

[storage]
bucket=tenant-a-storage
region=us-east-1
EOF
    
    # 租户B配置
    local tenant_b_ini="$TEST_DIR/tenant_b.ini"
    cat > "$tenant_b_ini" << 'EOF'
[tenant]
id=tenant_b
name=Company B

[database]
host=db-tenant-b.example.com
database=tenant_b_db

[storage]
bucket=tenant-b-storage
region=eu-west-1
EOF
    
    config_init 2>/dev/null
    config_load "$tenant_a_ini" "tenant_a" 2>/dev/null
    config_load "$tenant_b_ini" "tenant_b" 2>/dev/null
    
    # 验证租户配置隔离
    local tenant_a_db=$(config_get "tenant_a" "database.database" 2>/dev/null)
    assert_equals "tenant_a_db" "$tenant_a_db"
    
    local tenant_b_db=$(config_get "tenant_b" "database.database" 2>/dev/null)
    assert_equals "tenant_b_db" "$tenant_b_db"
    
    assert_not_equals "$tenant_a_db" "$tenant_b_db"
}

# 场景6: 配置迁移和兼容性
test_scenario_configuration_migration() {
    # 旧版本配置（INI格式）
    local legacy_ini="$TEST_DIR/legacy.ini"
    cat > "$legacy_ini" << 'EOF'
[application]
name=LegacyApp
version=1.0.0

[server]
port=8080
EOF
    
    config_init 2>/dev/null
    config_load "$legacy_ini" "legacy" 2>/dev/null
    
    # 读取旧配置
    local app_name=$(config_get "legacy" "application.name" 2>/dev/null)
    local app_version=$(config_get "legacy" "application.version" 2>/dev/null)
    local server_port=$(config_get "legacy" "server.port" 2>/dev/null)
    
    # 创建新版本配置（YAML格式）
    local modern_yaml="$TEST_DIR/modern.yaml"
    echo "{}" > "$modern_yaml"
    config_load "$modern_yaml" "modern" 2>/dev/null
    
    # 迁移配置到新格式
    config_set "modern" ".application.name" "$app_name" "string" 2>/dev/null
    config_set "modern" ".application.version" "$app_version" "string" 2>/dev/null
    config_set "modern" ".server.port" "$server_port" "number" 2>/dev/null
    
    # 验证迁移成功
    local migrated_name=$(config_get "modern" ".application.name" 2>/dev/null)
    assert_equals "$app_name" "$migrated_name"
    
    # 旧配置仍然可用（向后兼容）
    local legacy_name=$(config_get "legacy" "application.name" 2>/dev/null)
    assert_equals "$app_name" "$legacy_name"
}

# 场景7: 配置验证和错误处理
test_scenario_error_handling() {
    local invalid_yaml="$TEST_DIR/invalid.yaml"
    local valid_json="$TEST_DIR/valid.json"
    
    # 创建无效的YAML
    echo "invalid: yaml: content:" > "$invalid_yaml"
    
    # 创建有效的JSON
    echo '{"valid":"json"}' > "$valid_json"
    
    config_init 2>/dev/null
    
    # 加载无效配置应该失败
    if config_load "$invalid_yaml" "invalid" 2>/dev/null; then
        return 1
    fi
    
    # 加载有效配置应该成功
    config_load "$valid_json" "valid" 2>/dev/null
    
    # 读取不存在的配置应该返回默认值
    local nonexistent=$(config_get "valid" ".nonexistent.key" "default_value" 2>/dev/null)
    assert_equals "default_value" "$nonexistent"
}

###############################################################################
# 运行测试
###############################################################################

test_suite_start "真实场景集成测试"

run_test "场景1: Web应用配置管理" test_scenario_web_application
run_test "场景2: 微服务配置中心" test_scenario_microservices
run_test "场景3: CI/CD流水线配置" test_scenario_cicd_pipeline
run_test "场景4: 配置热更新场景" test_scenario_hot_reload
run_test "场景5: 多租户配置隔离" test_scenario_multi_tenant
run_test "场景6: 配置迁移和兼容性" test_scenario_configuration_migration
run_test "场景7: 配置验证和错误处理" test_scenario_error_handling

test_suite_end

cleanup_test_dir "$TEST_DIR"

test_report
exit $?

